!AGGIUNTE ISTRUZIONI***************************************************

! Ogni NPC deve essere di classe Character, e deve avere le funzioni
! SayQ(x) e Respond(x), che stampano l'x-esimo titolo e la x-esima
! risposta; inoltre Respond normalmente fa altre cose, oltre a 
! stampare la risposta.
!
! Ogni NPC deve avere anche una funzione InitQuips(), che deve
! inizializzare (vedi sotto) i 'quip' (flag che indicano se una certa 
! coppia frase/risposta e' attiva o no) che sono attivi di default 
! (all'inizio dell'avventura). Si dovrebbe mettere la seguente riga
! nella funzione initialize (definendo la variabile o, ovviamente)
!   objectloop (o ofclass Character) { o.InitQuips(); }
!
! NPC.SetQuip(42, 1) attiva il 42-esimo quip di NPC, NPC.SetQuip(42, 0)
! lo disattiva. NPC.QuipOn(42) e NPC.QuipOff(42) sono abbreviazioni
! per gli stessi comandi. NPC.QuipsOff(N, a, b, ...) disattiva N quips
! indicati dagli argomenti successivi (a, b, ...); N varia da 0 a 6, 
! visto che inform accetta al massimo 7 argomenti per funzione.
! NCP.QuipsOn(N, a, b, ...) fa esattamente cio' che pensate.
! Finalmente NPC.TestQuip(42) restituisce il valore (1 o 0) del
! 42-esimo quip.
!
! Di default si possono usare 56 quip, numerati da 0 a 55.
! Se si definisce la costante PH_SINGLE_PRESS, la libreria accetta come scelta la
! pressione di un singolo tasto (numerico). Ovviamente in questo
! caso ci possono essere in ogni istante solo 9 opzioni di dialogo 
! possibili (solo nove quip attivi).
! per uscire dal dialogo, la risposta deve ritornare FALSE, se invece restituisce TRUE
! allora il dialogo continua.


!AGGIUNTA ISTRUZIONE PER EVITARE INUTILI WARNING*************
System_file;
!************************************************************

Property NoTalk;

[AToI buf
    i n s ret;
    
    s = false;
    ret = 0;
    for (i = 2: i < buf->1 + 2: i++) {
        n = buf->i - '0';
        if (n >= 0 && n <= 9) {
            ret = 10 * ret + n;
            s = true;
        } else if (s == true) {
            break; 
        }
    }
    
    return ret;
];

Class Character 
  with
    qflag 0 0 0 0 0 0 0, ! 56 should be enough
    MAXQUIP 55,  ! like a constant
    startTalk [x z ok selected;
        
        do {
            ok = 0;
            for (x=0 : x <= self.MAXQUIP : x++) {
                if (self.TestQuip(x)) { ok++; }
            }
            
            if (ok > 0) {
                ! List the lines you have to choose from.
                z = 0;                  
                for (x=0: x <= self.MAXQUIP: x++) {
                    if (self.TestQuip(x)) {
                        z++;
                        print "[", z, "] ";
                        self.SayQ(x);
                    }
                }
                
                ! Get the choice and respond to it.
                do {
                    print (string)LibMessages(6);

!AGGIUNTA LA POSSIBILITA DI USARE LA PRESSIONE DEL SINGOLO TASTO PER LA SELEZIONE
!(che si ridurranno da 0 a 8 naturalmente
		    #Ifdef TALK_SINGLE_PRESS;
			@read_char 1 -> selected;
			print (char) selected, "";
			selected=selected-48;
		    #Ifnot;
!********************************************************************************
                    read buffer 0;
                    selected = AToI(buffer);
		    #Endif;
                } until ((selected > 0) && (selected <= z));
                
                ok = 0; 
                new_line;
                for (x=0: x <= self.MAXQUIP: x++) {
                    if (self.TestQuip(x)) {
                        ok++;
                        if (ok == selected) {
                            print "- "; self.SayQ(x);
                            print "- "; 
                            if (self.Respond(x) == false) {
                                new_line;
                                new_line;
                                rtrue;                     
                            }    
                            new_line;
                        }
                    }
                }
            }
        } until (ok == 0);
    ],
    SetQuip [line onoff     
        y z;
        
        if (line > self.MAXQUIP) {
            rfalse;    
        }
        y = line / 8;  ! y is the bytecount
        z = line % 8;  ! z is the bitnum
        z = TwoPower(z);  ! now a byte with only that bit set
        if (onoff == 1) {
            self.&qflag->y = self.&qflag->y | z; }
        if (onoff == 0) {
            self.&qflag->y = self.&qflag->y & ~z; }
    ],
    QuipOn  [line; self.SetQuip(line, 1); ],
    QuipOff [line; self.SetQuip(line, 0); ],
    QuipsOn [n a b c d e f; ! this function can probably be written better
        if ((n < 0) || (n > 6)) { ! 0 is ignored
            rfalse;
        }
        if (n == 0) return; self.QuipOn(a);
        if (n == 1) return; self.QuipOn(b);
        if (n == 2) return; self.QuipOn(c);
        if (n == 3) return; self.QuipOn(d);
        if (n == 4) return; self.QuipOn(e);
        if (n == 5) return; self.QuipOn(f);
    ],
    QuipsOff [n a b c d e f; ! this function can probably be written better
        if ((n < 0) || (n > 6)) { ! 0 is ignored
            rfalse;
        }
        if (n == 0) return; self.QuipOff(a);
        if (n == 1) return; self.QuipOff(b);
        if (n == 2) return; self.QuipOff(c);
        if (n == 3) return; self.QuipOff(d);
        if (n == 4) return; self.QuipOff(e);
        if (n == 5) return; self.QuipOff(f);
    ],    
    TestQuip [line      
        y z;
        
        if (line > self.MAXQUIP) {
            rfalse;
        }
        y = line / 8;
        z = line % 8;
        z = TwoPower(z);
        if (self.&qflag->y & z == z)
            rtrue;
        rfalse;
    ],
    SayQ [; ],
    Respond [; ],
    InitQuips [; ];

[TwoPower a;
    switch(a) {
        0: return $$000000001;
        1: return $$000000010;
        2: return $$000000100;
        3: return $$000001000;
        4: return $$000010000;
        5: return $$000100000;
        6: return $$001000000;
        7: return $$010000000;
    }
];
